package cn.edu.sgu.www.mhxysy.service.chongwu.impl;

import cn.edu.sgu.www.mhxysy.consts.CustomDirectories;
import cn.edu.sgu.www.mhxysy.consts.CustomMessages;
import cn.edu.sgu.www.mhxysy.dto.chongwu.ChongwuCategoryDTO;
import cn.edu.sgu.www.mhxysy.entity.chongwu.ChongwuCategory;
import cn.edu.sgu.www.mhxysy.exception.GlobalException;
import cn.edu.sgu.www.mhxysy.mapper.chongwu.ChongwuCategoryMapper;
import cn.edu.sgu.www.mhxysy.pager.Pager;
import cn.edu.sgu.www.mhxysy.pager.chongwu.ChongwuCategoryPager;
import cn.edu.sgu.www.mhxysy.redis.repository.impl.ChongwuCategoryRepository;
import cn.edu.sgu.www.mhxysy.restful.ResponseCode;
import cn.edu.sgu.www.mhxysy.service.chongwu.ChongwuCategoryService;
import cn.edu.sgu.www.mhxysy.util.ImageUpdater;
import cn.edu.sgu.www.mhxysy.util.ObjectUtils;
import cn.edu.sgu.www.mhxysy.util.UploadUtils;
import cn.edu.sgu.www.mhxysy.util.WrapperUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;
import java.util.function.Consumer;

/**
 * @author 沐雨橙风ιε
 * @version 1.0
 */
@Service
public class ChongwuCategoryServiceImpl implements ChongwuCategoryService {

	private final UploadUtils uploadUtils;
	private final ImageUpdater imageUpdater;
	private final ChongwuCategoryMapper chongwuCategoryMapper;
	private final ChongwuCategoryRepository chongwuCategoryRepository;

	@Autowired
	public ChongwuCategoryServiceImpl(
			UploadUtils uploadUtils,
			ImageUpdater imageUpdater,
			ChongwuCategoryMapper chongwuCategoryMapper,
			ChongwuCategoryRepository chongwuCategoryRepository) {
		this.uploadUtils = uploadUtils;
		this.imageUpdater = imageUpdater;
		this.chongwuCategoryMapper = chongwuCategoryMapper;
		this.chongwuCategoryRepository = chongwuCategoryRepository;
	}

	@Override
	public String upload(MultipartFile file) throws IOException {
		String directory = CustomDirectories.DIRECTORY_CW;

		return uploadUtils.upload(file, directory);
	}

	@Override
	public void insert(ChongwuCategoryDTO chongwuCategoryDTO) {
		QueryWrapper<ChongwuCategory> queryWrapper = new QueryWrapper<>();

		queryWrapper.eq("name", chongwuCategoryDTO.getName());

		Long count = chongwuCategoryMapper.selectCount(queryWrapper);

		if (count > 0) {
			throw new GlobalException(ResponseCode.BAD_REQUEST, "宠物名称重复！");
		}

		ChongwuCategory chongwuCategory = toEntity(chongwuCategoryDTO);

		chongwuCategory.setId(null);

		chongwuCategoryMapper.insert(chongwuCategory);
	}

	@Override
	public void updateById(ChongwuCategoryDTO chongwuCategoryDTO) {
		Integer categoryId = chongwuCategoryDTO.getId();

		ObjectUtils.requireNonNull(categoryId, CustomMessages.ID_NOT_NULL);

		QueryWrapper<ChongwuCategory> queryWrapper = new QueryWrapper<>();

		queryWrapper.eq("name", chongwuCategoryDTO.getName());
		queryWrapper.ne("id", categoryId);

		Long count = chongwuCategoryMapper.selectCount(queryWrapper);

		if (count > 0) {
			throw new GlobalException(ResponseCode.BAD_REQUEST, "宠物名称重复！");
		}

		ChongwuCategory chongwuCategory = toEntity(chongwuCategoryDTO);

		chongwuCategoryMapper.updateById(chongwuCategory);
	}

	@Override
	public void updateImageById(Integer id, String image) {
		imageUpdater.updateImageById(image, new Consumer<Object>() {
			@Override
			public void accept(Object o) {
				UpdateWrapper<ChongwuCategory> updateWrapper = WrapperUtils.getUpdateWrapper(id, image);

				chongwuCategoryMapper.update(updateWrapper.getEntity(), updateWrapper);
			}
		});
	}

	@Override
	public List<ChongwuCategory> selectAll() {
		return chongwuCategoryRepository.selectList();
	}

	@Override
	public List<ChongwuCategory> selectSpecial() {
		QueryWrapper<ChongwuCategory> queryWrapper = new QueryWrapper<>();

		// 特殊宠寿命为：限时：-1、永生：0
		// select * from chongwu_category where lifespan <= 0 or type >= 3;
		queryWrapper.le("lifespan", 0);
		queryWrapper.or();
		queryWrapper.ge("type", 3);

		queryWrapper.last("order by ifnull(special_type, 0), grade, type");

		return chongwuCategoryMapper.selectList(queryWrapper);
	}

	@Override
	public ChongwuCategory selectById(Integer id) {
		return chongwuCategoryRepository.selectById(id.toString());
	}

	@Override
	public Page<ChongwuCategory> selectByPage(ChongwuCategoryPager pager) {
		QueryWrapper<ChongwuCategory> queryWrapper = new QueryWrapper<>();
		Page<ChongwuCategory> page = Pager.ofPage(pager);

		queryWrapper.eq(
				pager.getType() != null,
				"type", pager.getType()
		);
		queryWrapper.eq(
				pager.getGrade() != null,
				"grade", pager.getGrade()
		);
		queryWrapper.last("order by ifnull(special_type, 0), grade, type");

		return chongwuCategoryMapper.selectPage(page, queryWrapper);
	}

	@Override
	public List<ChongwuCategory> selectByGradeRange(Integer min, Integer max) {
		QueryWrapper<ChongwuCategory> queryWrapper = new QueryWrapper<>();

		// 查询指定等级的非特殊宠物
		// select * from chongwu_category
		// where lifespan > 0 and grade between #{min} and #{max} order by grade asc
		queryWrapper.gt("lifespan", 0);
		queryWrapper.between("grade", min, max);

		queryWrapper.orderByAsc("grade");

		return chongwuCategoryMapper.selectList(queryWrapper);
	}

	private ChongwuCategory toEntity(ChongwuCategoryDTO chongwuCategoryDTO) {
		ChongwuCategory chongwuCategory = new ChongwuCategory();

		chongwuCategory.setId(chongwuCategoryDTO.getId());
		chongwuCategory.setName(chongwuCategoryDTO.getName());
		chongwuCategory.setType(chongwuCategoryDTO.getType());
		chongwuCategory.setGrade(chongwuCategoryDTO.getGrade());
		chongwuCategory.setLifespan(chongwuCategoryDTO.getLifespan());
		chongwuCategory.setNeidanId(chongwuCategoryDTO.getNeidanId());
		chongwuCategory.setSpecialType(chongwuCategoryDTO.getSpecialType());
		chongwuCategory.setNeidanQuantity(chongwuCategoryDTO.getNeidanQuantity());

		return chongwuCategory;
	}

}